import { watch } from 'vue'
import { useHistoryStore } from './history'
import { useSearchStore } from './search'
import { useRecoveryStore } from './recovery'
import { useUIStore } from './ui'
import { useDiffStore } from './diff'
import { useEventBus } from './events'

// Store integration manager
export class StoreIntegration {
  private static instance: StoreIntegration
  private eventBus = useEventBus()
  
  static getInstance(): StoreIntegration {
    if (!StoreIntegration.instance) {
      StoreIntegration.instance = new StoreIntegration()
    }
    return StoreIntegration.instance
  }
  
  private constructor() {
    this.setupIntegrations()
  }
  
  private setupIntegrations() {
    this.setupHistoryIntegration()
    this.setupSearchIntegration()
    this.setupRecoveryIntegration()
    this.setupDiffIntegration()
    this.setupUIIntegration()
  }
  
  private setupHistoryIntegration() {
    const historyStore = useHistoryStore()
    const uiStore = useUIStore()
    
    // Watch for version selection changes
    watch(
      () => historyStore.currentVersion,
      (newVersion, oldVersion) => {
        if (newVersion !== oldVersion && newVersion) {
          this.eventBus.emit('history:version-selected', { versionId: newVersion })
          
          // Update UI state
          uiStore.showInfo('版本已切换', `已切换到版本 ${newVersion}`)
        }
      }
    )
    
    // Watch for file selection changes
    watch(
      () => historyStore.selectedFiles,
      (newSelection, oldSelection) => {
        if (newSelection.length !== oldSelection?.length) {
          this.eventBus.emit('history:files-selected', { fileIds: newSelection })
          
          // Show selection info
          if (newSelection.length > 0) {
            uiStore.showInfo('文件已选择', `已选择 ${newSelection.length} 个文件`)
          }
        }
      },
      { deep: true }
    )
    
    // Watch for loading state
    watch(
      () => historyStore.isLoading,
      (isLoading) => {
        if (isLoading) {
          uiStore.startLoading('正在加载历史数据...')
        } else {
          uiStore.stopAllLoading()
        }
      }
    )
    
    // Watch for errors
    watch(
      () => historyStore.error,
      (error) => {
        if (error) {
          uiStore.showError('历史数据错误', error)
        }
      }
    )
  }
  
  private setupSearchIntegration() {
    const searchStore = useSearchStore()
    const uiStore = useUIStore()
    useHistoryStore()
    
    // Watch for search state changes
    watch(
      () => searchStore.isSearching,
      (isSearching) => {
        if (isSearching) {
          uiStore.startLoading('正在搜索...')
        } else {
          uiStore.stopAllLoading()
        }
      }
    )
    
    // Watch for search results
    watch(
      () => searchStore.totalResults,
      (totalResults) => {
        if (totalResults > 0) {
          uiStore.showSuccess('搜索完成', `找到 ${totalResults} 个结果`)
          this.eventBus.emit('search:results-updated', { 
            results: searchStore.results, 
            total: totalResults 
          })
        }
      }
    )
    
    // Watch for search errors
    watch(
      () => searchStore.error,
      (error) => {
        if (error) {
          uiStore.showError('搜索失败', error)
        }
      }
    )
    
    // Auto-update search context when history version changes
    this.eventBus.on('history:version-selected', ({ versionId }) => {
      // Update search options to include current version
      searchStore.updateSearchOptions({
        versionIds: [versionId]
      })
    })
  }
  
  private setupRecoveryIntegration() {
    const recoveryStore = useRecoveryStore()
    const uiStore = useUIStore()
    
    // Watch for recovery state changes
    watch(
      () => recoveryStore.isRecovering,
      (isRecovering) => {
        if (isRecovering) {
          const loadingId = uiStore.startLoading('正在恢复文件...', {
            cancellable: true,
            onCancel: () => recoveryStore.cancelRecovery()
          })
          
          // Watch for progress updates
          const unwatch = watch(
            () => recoveryStore.progress,
            (progress) => {
              uiStore.updateLoading(loadingId, {
                message: `正在恢复文件... ${Math.round(progress)}%`,
                progress
              })
            }
          )
          
          // Stop watching when recovery completes
          watch(
            () => recoveryStore.isRecovering,
            (stillRecovering) => {
              if (!stillRecovering) {
                unwatch()
                uiStore.stopLoading(loadingId)
              }
            },
            { once: true }
          )
        }
      }
    )
    
    // Watch for recovery queue changes
    watch(
      () => recoveryStore.recoveryQueue.length,
      (queueLength, oldLength) => {
        if (queueLength > (oldLength || 0)) {
          uiStore.showInfo('任务已添加', `恢复队列中有 ${queueLength} 个任务`)
        }
      }
    )
    
    // Watch for completed recoveries
    watch(
      () => recoveryStore.completedRecoveries.length,
      (completedCount) => {
        if (completedCount > 0) {
          this.eventBus.emit('recovery:batch-completed', {
            successful: recoveryStore.completedRecoveries.length,
            failed: recoveryStore.failedRecoveries.length
          })
        }
      }
    )
    
    // Watch for recovery errors
    watch(
      () => recoveryStore.error,
      (error) => {
        if (error) {
          uiStore.showError('恢复失败', error)
        }
      }
    )
  }

  private setupDiffIntegration() {
    const diffStore = useDiffStore()
    const uiStore = useUIStore()
    
    // Watch for diff loading state
    watch(
      () => diffStore.isLoading,
      (isLoading) => {
        if (isLoading) {
          uiStore.startLoading('正在加载文件对比...')
        } else {
          uiStore.stopAllLoading()
        }
      }
    )
    
    // Watch for diff errors
    watch(
      () => diffStore.error,
      (error) => {
        if (error) {
          uiStore.showError('文件对比失败', error)
        }
      }
    )
    
    // Watch for successful diff completion
    watch(
      () => diffStore.hasDiff,
      (hasDiff) => {
        if (hasDiff && diffStore.diffStats) {
          const stats = diffStore.diffStats
          uiStore.showSuccess(
            '对比完成', 
            `发现 ${stats.total} 处变更 (+${stats.additions} -${stats.deletions} ~${stats.modifications})`
          )
          
          this.eventBus.emit('diff:comparison-completed', {
            leftFile: diffStore.leftFile,
            rightFile: diffStore.rightFile
          })
        }
      }
    )
    
    // Watch for file selection changes
    watch(
      () => [diffStore.leftFile, diffStore.rightFile],
      ([leftFile, rightFile]) => {
        if (leftFile && rightFile) {
          this.eventBus.emit('diff:files-selected', { leftFile, rightFile })
        }
      },
      { deep: true }
    )
  }
  
  private setupUIIntegration() {
    const uiStore = useUIStore()
    
    // Handle keyboard shortcuts
    if (typeof window !== 'undefined') {
      window.addEventListener('keydown', (event) => {
        uiStore.handleKeydown(event)
      })
      
      // Handle window resize
      window.addEventListener('resize', () => {
        uiStore.updateWindowSize(window.innerWidth, window.innerHeight)
      })
      
      // Initialize window size
      uiStore.updateWindowSize(window.innerWidth, window.innerHeight)
    }
    
    // Setup default keyboard shortcuts
    this.setupDefaultShortcuts()
  }
  
  private setupDefaultShortcuts() {
    const uiStore = useUIStore()
    const historyStore = useHistoryStore()
    const searchStore = useSearchStore()
    const recoveryStore = useRecoveryStore()
    
    // Global shortcuts
    uiStore.registerShortcut('ctrl+/', () => {
      uiStore.showInfo('键盘快捷键', '按 Ctrl+/ 查看所有快捷键')
    })
    
    uiStore.registerShortcut('ctrl+shift+t', () => {
      uiStore.toggleTheme()
    })
    
    uiStore.registerShortcut('ctrl+b', () => {
      uiStore.toggleSidebar()
    })
    
    // History shortcuts
    uiStore.registerShortcut('ctrl+r', () => {
      historyStore.loadVersions()
    })
    
    uiStore.registerShortcut('ctrl+a', () => {
      if (uiStore.currentView === 'history') {
        historyStore.selectAllFiles()
      }
    })
    
    uiStore.registerShortcut('escape', () => {
      historyStore.clearSelection()
      searchStore.clearResults()
      uiStore.closeDialog()
    })
    
    // Search shortcuts
    uiStore.registerShortcut('ctrl+f', () => {
      uiStore.setCurrentView('search')
    })
    
    uiStore.registerShortcut('ctrl+shift+f', () => {
      searchStore.setSearchType('content')
      uiStore.setCurrentView('search')
    })
    
    // Recovery shortcuts
    uiStore.registerShortcut('ctrl+shift+r', () => {
      if (recoveryStore.hasQueuedTasks) {
        recoveryStore.recoverBatch()
      }
    })
    
    uiStore.registerShortcut('ctrl+shift+c', () => {
      recoveryStore.clearQueue()
    })
  }
}

// Cache management
export class CacheManager {
  private static instance: CacheManager
  private caches = new Map<string, Map<string, any>>()
  private eventBus = useEventBus()
  
  static getInstance(): CacheManager {
    if (!CacheManager.instance) {
      CacheManager.instance = new CacheManager()
    }
    return CacheManager.instance
  }
  
  private constructor() {
    this.setupCacheInvalidation()
  }
  
  private setupCacheInvalidation() {
    // Invalidate caches when version changes
    this.eventBus.on('history:version-selected', () => {
      this.invalidateCache('file-content')
      this.invalidateCache('file-tree')
    })
    
    // Invalidate search cache when search options change
    this.eventBus.on('search:query-changed', () => {
      this.invalidateCache('search-results')
    })
  }
  
  getCache(cacheType: string): Map<string, any> {
    if (!this.caches.has(cacheType)) {
      this.caches.set(cacheType, new Map())
    }
    return this.caches.get(cacheType)!
  }
  
  set(cacheType: string, key: string, value: any, ttl?: number) {
    const cache = this.getCache(cacheType)
    const item = {
      value,
      timestamp: Date.now(),
      ttl: ttl || 0
    }
    
    cache.set(key, item)
    
    this.eventBus.emit('cache:updated', { type: cacheType, key, data: value })
  }
  
  get(cacheType: string, key: string): any | null {
    const cache = this.getCache(cacheType)
    const item = cache.get(key)
    
    if (!item) return null
    
    // Check TTL
    if (item.ttl > 0 && Date.now() - item.timestamp > item.ttl) {
      cache.delete(key)
      return null
    }
    
    return item.value
  }
  
  has(cacheType: string, key: string): boolean {
    return this.get(cacheType, key) !== null
  }
  
  delete(cacheType: string, key: string) {
    const cache = this.getCache(cacheType)
    cache.delete(key)
  }
  
  invalidateCache(cacheType: string) {
    if (this.caches.has(cacheType)) {
      this.caches.get(cacheType)!.clear()
      this.eventBus.emit('cache:invalidated', { type: cacheType as any })
    }
  }
  
  invalidateAll() {
    this.caches.clear()
    this.eventBus.emit('cache:invalidated', { type: 'all' })
  }
  
  getCacheStats() {
    const stats: Record<string, { size: number, keys: string[] }> = {}
    
    this.caches.forEach((cache, type) => {
      stats[type] = {
        size: cache.size,
        keys: Array.from(cache.keys())
      }
    })
    
    return stats
  }
}

// Initialize integrations
export function initializeStoreIntegrations() {
  StoreIntegration.getInstance()
  CacheManager.getInstance()
}

// Composable for accessing integrated stores
export function useStores() {
  const historyStore = useHistoryStore()
  const searchStore = useSearchStore()
  const recoveryStore = useRecoveryStore()
  const uiStore = useUIStore()
  const diffStore = useDiffStore()
  
  return {
    history: historyStore,
    search: searchStore,
    recovery: recoveryStore,
    ui: uiStore,
    diff: diffStore
  }
}

// Composable for cache management
export function useCache() {
  const cacheManager = CacheManager.getInstance()
  
  return {
    set: cacheManager.set.bind(cacheManager),
    get: cacheManager.get.bind(cacheManager),
    has: cacheManager.has.bind(cacheManager),
    delete: cacheManager.delete.bind(cacheManager),
    invalidate: cacheManager.invalidateCache.bind(cacheManager),
    invalidateAll: cacheManager.invalidateAll.bind(cacheManager),
    getStats: cacheManager.getCacheStats.bind(cacheManager)
  }
}